import type {
  AxiosError,
  AxiosHeaders,
  AxiosInstance,
  AxiosRequestConfig,
  AxiosRequestHeaders,
  AxiosResponse,
  InternalAxiosRequestConfig,
  Method,
} from 'axios';
import { ElMessage } from 'element-plus';
import type { HeadersInterface } from './type';

const config: AxiosRequestConfig = {
  baseURL: axiosConfig.base_url,
  timeout: axiosConfig.request_timeout,
  withCredentials: true,
};

const instance: AxiosInstance = axios.create(config);

instance.interceptors.request.use(
  (config: InternalAxiosRequestConfig): InternalAxiosRequestConfig => {
    const headers: HeadersInterface = {
      'Content-Type': 'application/json',
      'x-requested-with': 'XMLHttpRequest',
    };
    if (useMicroAppStore()?.currentApp?.id) {
      headers['GATEWAY-SYSTEM'] = useMicroAppStore()?.currentApp?.id;
    }
    config.headers = {
      ...headers,
      ...config.headers,
    } as unknown as AxiosRequestHeaders;
    return config;
  },
  (error) => {
    ElMessage.error('请求失败');
    return Promise.reject(error);
  },
);

instance.interceptors.response.use(
  (response: AxiosResponse) => {
    return response.data;
  },
  (error: AxiosError) => {
    if (error.response) {
      const { status } = error.response;
      switch (status) {
        case 400:
          ElMessage.error('请求无效');
          break;
        case 401:
          localStorage.clear();
          sessionStorage.clear();
          location.href = `${location.protocol}//${location.host}/login/callback?redirect_uri=${encodeURIComponent(location.href)}`;
          break;
        case 403:
          ElMessage.error('无访问权限');
          break;
        case 404:
          ElMessage.error('无法找到文件');
          break;
        case 405:
          ElMessage.error('资源被禁止');
          break;
        case 408:
          ElMessage.error('请求超时');
          break;
        case 500:
          ElMessage.error('500!服务器错误');
          break;
        case 504:
          ElMessage.error('网关超时');
          break;
        default:
          ElMessage.error('error');
      }
    }
    return Promise.reject(error);
  },
);

export interface ResponseData<R> {
  code: string;
  msg: string;
  data: R;
  ok: boolean;
}

export interface User {
  id: number;
  name: string;
  email: string;
}

const request = async <R, P>(
  url: string,
  method: Method,
  data?: P,
  headers?: AxiosHeaders,
): Promise<R> => {
  return instance.request({
    url,
    method,
    [method.toLowerCase() === 'get' ? 'params' : 'data']: data,
    headers,
  });
};

export default request;
